home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / linux / tools / gtar10.lha / port.c < prev    next >
C/C++ Source or Header  |  1992-09-09  |  28KB  |  1,329 lines

  1. /* Supporting routines which may sometimes be missing.
  2.    Copyright (C) 1988 Free Software Foundation
  3.  
  4. This file is part of GNU Tar.
  5.  
  6. GNU Tar is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU Tar is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Tar; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * @(#)port.c 1.15    87/11/05    by John Gilmore, 1986
  22.  *
  23.  * These are routines not available in all environments.
  24.  *
  25.  * I know this introduces an extra level of subroutine calls and is
  26.  * slightly slower.  Frankly, my dear, I don't give a damn.  Let the
  27.  * Missed-Em Vee losers suffer a little.  This software is proud to
  28.  * have been written on a BSD system.
  29.  */
  30. #include <stdio.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include <signal.h>
  34. #include <errno.h>
  35.  
  36. #if    defined(__MSDOS__) || defined(USG)
  37. #include <fcntl.h>
  38. #else
  39. #include <sys/file.h>
  40. #endif
  41.  
  42. #include "tar.h"
  43. #include "port.h"
  44.  
  45. #ifdef USG
  46. #include <string.h>
  47. #else
  48. extern size_t strlen();
  49. #endif
  50.  
  51. extern long baserec;
  52. /*
  53.  * Some people (e.g. V7) don't have a #define for these.
  54.  */
  55. #ifndef    O_BINARY
  56. #define    O_BINARY    0
  57. #endif
  58. #ifndef    O_RDONLY
  59. #define    O_RDONLY    0
  60. #endif
  61. #ifndef NULL
  62. #define NULL 0
  63. #endif
  64.  
  65. /* JF: modified so all configuration information can appear here, instead of
  66.    being scattered through the file.  Add all the machine-dependent #ifdefs
  67.    here */
  68. #undef WANT_DUMB_GET_DATE/* WANT_DUMB_GET_DATE --> get_date() */
  69. #undef WANT_VALLOC    /* WANT_VALLOC --> valloc() */
  70. #undef WANT_MKDIR    /* WANT_MKDIR --> mkdir() rmdir() */
  71. #undef WANT_STRING    /* WANT_STRING --> index() bcopy() bzero() bcmp() */
  72. #undef WANT_BZERO    /* WANT_BZERO --> bzero() bcmp() execlp() */
  73.             /* EMUL_OPEN3 --> open3() */
  74. #undef WANT_MKNOD    /* WANT_MKNOD --> mknod() link() chown() geteuid() */
  75. #undef WANT_UTILS    /* WANT_UTILS --> panic() ck_*() *_buffer()
  76.                merge_sort() quote_copy_string() un_quote_string() */
  77. #undef WANT_CK_PIPE    /* WANT_CK_PIPE --> ck_pipe() */
  78. #undef WANT_GETWD    /* WANT_GETWD --> getwd() */
  79. #undef WANT_STRSTR    /* WANT_STRSTR --> strstr() */
  80. #undef WANT_FTRUNCATE    /* WANT_FTRUNCATE --> frtruncate() */
  81.  
  82. /* Define only ONE of these four . . . */
  83. /* #undef DOPRNT_MSG    /* Define this one if you have _doprnt() and
  84.                no varargs support */
  85. /* #undef VARARGS_MSG    /* Define this one if you have varargs.h and
  86.                vfprintf() */
  87. /* #undef STDC_MSG     /* Define this one if you are using ANSI C and
  88.                and have vfprintf() */
  89. /* #undef LOSING_MSG    /* Define this one if you don't have any of the
  90.                above */
  91. #ifdef USG
  92. #define WANT_STRING
  93. #define WANT_VALLOC
  94.  
  95. #if defined(sgi) && defined(mips)
  96. #define WANT_GETWD
  97. #endif
  98.  
  99. #if defined(i386)
  100. #define WANT_FTRUNCATE
  101. #endif
  102.  
  103. #endif
  104.  
  105. #ifdef hpux
  106. #define WANT_VALLOC
  107. #endif
  108.  
  109. #ifdef MINIX
  110. #define WANT_BZERO
  111. #endif
  112.  
  113. #ifdef __MSDOS__
  114. char TTY_NAME[] = "con";
  115.  
  116. #define WANT_STRING
  117. #define WANT_MKNOD
  118. #define WANT_UTILS
  119. #define WANT_VALLOC
  120.  
  121. #if (!defined(STDC_MSG) && !defined(DOPRNT_MSG) && !defined(VARARGS_MSG) && !defined(LOSING_MSG))
  122. #ifdef __STDC__
  123. #define STDC_MSG
  124. #else
  125. #define LOSING_MSG
  126. #endif
  127. #endif
  128.  
  129. #else /* not MSDOS */
  130. #ifdef amigados
  131. char TTY_NAME[] = "*";
  132. #else
  133. char TTY_NAME[] ="/dev/tty";
  134. #endif
  135.  
  136. #define WANT_UTILS
  137. #define WANT_CK_PIPE
  138. #ifndef HAVE_STRSTR
  139. #define WANT_STRSTR
  140. #endif
  141.  
  142. #if (!defined(STDC_MSG) && !defined(DOPRNT_MSG) && !defined(VARARGS_MSG) && !defined(LOSING_MSG))
  143. #ifdef BSD42
  144. /* BSD systems should do this even if __STDC__, because
  145.    we might be using an ANSI compiler without an ANSI library. (sigh) */
  146. #ifdef sparc
  147. #define LOSING_MSG
  148. #else
  149. #define DOPRNT_MSG
  150. #endif
  151. #else /* not BSD */
  152. #ifdef __STDC__
  153. #define STDC_MSG
  154. #else /* not ANSI C */
  155. #define LOSING_MSG
  156. #endif /* not ANSI C */
  157. #endif /* not BSD */
  158. #endif /* Need to define some form of _MSG */
  159. #endif /* not MSDOS */
  160.  
  161. /* End of system-dependent #ifdefs */
  162.  
  163. #ifdef WANT_DUMB_GET_DATE
  164. /* JF a get_date() routine takes a date/time/etc and turns it into a time_t */
  165. /* This one is a quick hack I wrote in about five minutes to see if the N
  166.    option works.  Someone should replace it with one that works */
  167.  
  168. /* This get_date takes an arg of the form mm/dd/yyyy hh:mm:ss and turns it
  169.    into a time_t .  Its not well tested or anything. . .  */
  170. /* In general, you should use the get_date() supplied in getdate.y */
  171.  
  172. #define OFF_FROM GMT 18000        /* Change for your time zone! */
  173.  
  174. time_t
  175. get_date(str)
  176. char *str;
  177. {
  178.     int month,day,year,hour,minute,second;
  179.     time_t ret;
  180.     int    n;
  181.  
  182. #define SECS_PER_YEAR (365L*SECS_PER_DAY)
  183. #define SECS_PER_LEAP_YEAR (366L*SECS_PER_DAY)
  184.  
  185. #define SECS_PER_DAY (24L*60*60)
  186.     static int days_per_month[2][12] = {
  187.         31,28,31,30,31,30,31,31,30,31,30,31,
  188.         31,29,31,30,31,30,31,31,30,31,30,31
  189.     };
  190.  
  191.     static int days_per_year[2]={365,366};
  192.  
  193.     month=day=year=hour=minute=second=0;
  194.     n=sscanf(str,"%d/%d/%d %d:%d:%d",&month,&day,&year,&hour,&minute,&second);
  195.     if(n<3)
  196.         return 0;
  197.     if(year<100)
  198.         year+=1900;
  199.     if(year<1970)
  200.         return 0;
  201.     ret=0;
  202.  
  203.     ret+=OFF_FROM_GMT;
  204.  
  205.     for(n=1970;n<year;n++)
  206.         if(n%4==0 && n%400!=0)
  207.             ret+=SECS_PER_LEAP_YEAR;
  208.         else
  209.             ret+=SECS_PER_YEAR;
  210.  
  211.     month--;
  212.     for(n=0;n<month;n++) {
  213.         if(year%4==0 && year%400!=0)
  214.             ret+=SECS_PER_DAY*days_per_month[1][n];
  215.         else
  216.             ret+=SECS_PER_DAY*days_per_month[0][n];
  217.     }
  218.     ret+=SECS_PER_DAY*(day-1);
  219.     ret+=second+minute*60+hour*60*60;
  220.     return ret;
  221. }
  222. #endif
  223.  
  224. #ifdef WANT_VALLOC
  225. /*
  226.  * valloc() does a malloc() on a page boundary.  On some systems,
  227.  * this can make large block I/O more efficient.
  228.  */
  229. char *
  230. valloc (size)
  231.     unsigned size;
  232. {
  233.     extern char *malloc ();
  234.     return (malloc (size));
  235. }
  236. #endif
  237. /*
  238.  *                NMKDIR.C
  239.  *
  240.  * Written by Robert Rother, Mariah Corporation, August 1985. 
  241.  *
  242.  * I wrote this out of shear disgust with myself because I couldn't
  243.  * figure out how to do this in /bin/sh.
  244.  *
  245.  * If you want it, it's yours.  All I ask in return is that if you
  246.  * figure out how to do this in a Bourne Shell script you send me
  247.  * a copy.
  248.  *                    sdcsvax!rmr or rmr@uscd
  249. *
  250. * Severely hacked over by John Gilmore to make a 4.2BSD compatible
  251. * subroutine.    11Mar86; hoptoad!gnu
  252. *
  253. * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
  254. * subroutine didn't return EEXIST.  It does now.
  255. */
  256.  
  257. /*
  258.  * Make a directory.  Compatible with the mkdir() system call on 4.2BSD.
  259.  */
  260. #ifdef WANT_MKDIR
  261. int
  262. mkdir(dpath, dmode)
  263.     char *dpath;
  264.     int dmode;
  265. {
  266.     int cpid, status;
  267.     struct stat statbuf;
  268.     extern int errno;
  269.  
  270.     if (stat(dpath,&statbuf) == 0) {
  271.         errno = EEXIST;        /* Stat worked, so it already exists */
  272.         return -1;
  273.     }
  274.  
  275.     /* If stat fails for a reason other than non-existence, return error */
  276.     if (errno != ENOENT) return -1; 
  277.  
  278.     switch (cpid = fork()) {
  279.  
  280.     case -1:            /* Error in fork() */
  281.         return(-1);        /* Errno is set already */
  282.  
  283.     case 0:                /* Child process */
  284.         /*
  285.          * Cheap hack to set mode of new directory.  Since this
  286.          * child process is going away anyway, we zap its umask.
  287.          * FIXME, this won't suffice to set SUID, SGID, etc. on this
  288.          * directory.  Does anybody care?
  289.          */
  290.         status = umask(0);    /* Get current umask */
  291.         status = umask(status | (0777 & ~dmode)); /* Set for mkdir */
  292.         execl("/bin/mkdir", "mkdir", dpath, (char *)0);
  293.         _exit(-1);        /* Can't exec /bin/mkdir */
  294.     
  295.     default:            /* Parent process */
  296.         while (cpid != wait(&status)) ;    /* Wait for kid to finish */
  297.     }
  298.  
  299.     if (TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0) {
  300.         errno = EIO;        /* We don't know why, but */
  301.         return -1;        /* /bin/mkdir failed */
  302.     }
  303.  
  304.     return 0;
  305. }
  306. int
  307. rmdir(dpath)
  308.     char *dpath;
  309. {
  310.     int cpid, status;
  311.     struct stat statbuf;
  312.     extern int errno;
  313.  
  314.     if (stat(dpath,&statbuf) != 0) {
  315.         /* Stat just set errno.  We don't have to */
  316.         return -1;
  317.     }
  318.  
  319.     switch (cpid = fork()) {
  320.  
  321.     case -1:            /* Error in fork() */
  322.         return(-1);        /* Errno is set already */
  323.  
  324.     case 0:                /* Child process */
  325.         execl("/bin/rmdir", "rmdir", dpa